import numpy as np

# 1. 数值迭代：numpy.nditer()
"""
NumPy包含一个迭代器对象numpy.nditer。它是一个有效的多维迭
代器对象，可以用于在数组上进行迭代。数组的每个元素可使用
Python的标准Iterator接口来访问。
"""

# 使用arange()函数创建一个3×4数组，并使用nditer对它进行迭代。
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print("迭代前：")
print(a)
print()
print("迭代后：")
for i in np.nditer(a):
    print(i, end=" ")
print()
print()

# 迭代的顺序匹配数组的内容布局，而不考虑特定的排序。
# 这可以通过迭代上述数组的转置来看到

b = a.T
print("迭代前：")
print(b)
print()
print("迭代后：")
for i in np.nditer(b):
    print(i, end=" ")
print()
print()


# 可以通过显式提醒来强制nditer对象使用某种顺序。
print("原数组：")
print(b)
print()
print("以 C 风格进行排序：")  # 顺序匹配数组的内容布局
for i in np.nditer(b, order="C"):
    print(i, end=" ")
print()
print()
print("以 F 风格进行排序：")  # 从第一列向下排序，完毕后，第二列向下排……
for i in np.nditer(b, order="F"):
    print(i, end=" ")
print()
print()


"""
nditer类的构造器拥有flags参数，它可以接收下列值：
　c_index：可以跟踪C顺序的索引。
　f_index：可以跟踪Fortran顺序的索引。
　multi-index：每次迭代可以跟踪一种索引类型。
　external_loop：给出的值是具有多个值的一维数组，而不是零维数组。
"""

# nditer对象有另一个可选参数op_flags，其默认值为只读，
# 也可以设置为读写或只写模式。这将允许使用此迭代器修改数组元素。
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print("原数组：")
print(a)
print()
print()
print("迭代器修改数组：")
for i in np.nditer(a, op_flags=["readwrite"]):
    i[...] = i * 2
print(a)
print()
print()

# 迭代器遍历对应于每列的一维数组
print("原数组：")
print(a)
print("遍历每一层：")

# order = 'C' 则是所有元素在一个一维数组中
for i in np.nditer(a, flags=["external_loop"], order="F"):
    print(i, end=" ")
print()
print()


# 如果两个数组是可广播的，nditer组合对象就能够同时迭代它们。
a = np.arange(0, 60, 5)
a = a.reshape(3, 4)
print("第一个数组：")
print(a)
print()
b = np.arange(4)
print("第二个数组：")
print(b)
print()
print("同时迭代：")
for i, j in np.nditer([a, b]):
    print(f"{i}:{j}", end=" ")
    if j == 3:
        print()
print()
print()


# 2. 数值变形


# 3. 数组翻转


# 4. 修改维度


# 5. 数组连接


# 6. 数组分割


# 7. 添加 / 删除元素
